from loguru import logger
from datetime import datetime, timezone, timedelta, date as datetime_date
from .models import Card, ReviewLog
import json


def prepare_review_calendar_data():
    """
    准备复习日历数据
    """

    # 获取所有复习记录
    logs = ReviewLog.query.all()

    # 按日期统计复习次数
    date_counts = {}
    for log in logs:
        # 将UTC时间转换为用户本地时间
        utc_time = log.review_time.replace(tzinfo=timezone.utc)
        date = utc_time.date().isoformat()
        date_counts[date] = date_counts.get(date, 0) + 1

    # 如果无数据，使用最近一年的日期范围
    if not date_counts:
        end_date = datetime_date.today()
        begin_date = end_date - timedelta(days=365)
        data = [
            [str(begin_date + timedelta(days=i)), 0]
            for i in range((end_date - begin_date).days + 1)
        ]
    else:
        # 转换为pyecharts需要的格式
        data = [[date, count] for date, count in date_counts.items()]
    return data


def prepare_create_calendar_data():
    """
    生成创建日历
    """
    # 获取用户时区，默认为UTC

    # 获取所有卡片
    logs = Card.query.all()

    # 按日期统计创建次数
    date_counts = {}
    for log in logs:
        # 将UTC时间转换为用户本地时间
        utc_time = log.create_time.replace(tzinfo=timezone.utc)
        date = utc_time.date().isoformat()
        date_counts[date] = date_counts.get(date, 0) + 1

    # 如果无数据，使用最近一年的日期范围
    if not date_counts:
        end_date = datetime_date.today()
        begin_date = end_date - timedelta(days=365)
        data = [
            [str(begin_date + timedelta(days=i)), 0]
            for i in range((end_date - begin_date).days + 1)
        ]
    else:
        # 转换为pyecharts需要的格式
        data = [[date, count] for date, count in date_counts.items()]
    return data


def prepare_due_calendar_data():
    # 获取用户时区，默认为UTC

    # 获取所有卡片
    cards = Card.query.all()

    # 按日期统计卡片数量
    date_counts = {}
    for card in cards:
        # 将UTC时间转换为用户本地时间
        utc_time = card.due.replace(tzinfo=timezone.utc)
        date = utc_time.date().isoformat()
        date_counts[date] = date_counts.get(date, 0) + 1

    # 如果无数据，使用最近一年的日期范围
    if not date_counts:
        end_date = datetime_date.today()
        begin_date = end_date - timedelta(days=365)
        data = [
            [str(begin_date + timedelta(days=i)), 0]
            for i in range((end_date - begin_date).days + 1)
        ]
    else:
        # 转换为pyecharts需要的格式
        data = [[date, count] for date, count in date_counts.items()]
    return data


def prepare_rating_pie_data():
    """
    准备反馈饼图数据
    """
    # 获取所有反馈记录
    ratings = ReviewLog.query.filter(ReviewLog.rating != None).all()
    # 统计反馈
    rating_counts = {}
    for rating in ratings:
        rating_counts[rating.rating] = rating_counts.get(rating.rating, 0) + 1
    # 转换为pyecharts需要的格式
    data = [[rating, count] for rating, count in rating_counts.items()]
    return data


def update_plot_data(path, app=None):
    # If we're in a separate thread, we need to push an application context
    if app is not None:
        with app.app_context():
            _update_plot_data_impl(path)
    else:
        _update_plot_data_impl(path)


def _update_plot_data_impl(path):
    try:
        with open(path, encoding="utf-8", mode="r") as f:
            plot_data: dict = json.load(f)
    except Exception:
        plot_data = {}
    plot_data.update(
        {
            datetime_date.today().isoformat(): [
                prepare_review_calendar_data(),
                prepare_create_calendar_data(),
                prepare_due_calendar_data(),
                prepare_rating_pie_data(),
            ]
        }
    )
    with open(path, encoding="utf-8", mode="w") as f:
        json.dump(plot_data, f)
    logger.debug(f"更新图表数据:{datetime_date.today().isoformat()}")
